﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Coding4Fun.Kinect.Wpf.Controls;
using Microsoft.Kinect;
using Coding4Fun.Kinect.Wpf;
using System.IO;
using System.Timers;
using System.Windows.Threading;
using Microsoft.Speech.AudioFormat;
using Microsoft.Speech.Recognition;
using System.Threading;

namespace Oprah
{
    /// <summary>
    /// Interaction logic for FSF.xaml
    /// </summary>
    public partial class FSF : Window
    {
        
        string userans;
        int qnum = 1;
        int group = 1;
        int fsc = 0;
        string rightans;


        public FSF()
        {
            InitializeComponent();
            Random rand = new Random();
            int set = rand.Next(1, 2);
            Question.init(1);
            Images.init(1);

            var colorList = new List<Color> { Colors.Black, Colors.Green };
            this.bitmapWave = new WriteableBitmap(WaveImageWidth, WaveImageHeight, 96, 96, PixelFormats.Indexed1, new BitmapPalette(colorList));

            this.pixels = new byte[WaveImageWidth];
            for (int i = 0; i < this.pixels.Length; i++)
            {
                this.pixels[i] = 0xff;
            }

            //imgWav.Source = this.bitmapWave;

            kinectSensorChooser1.KinectSensorChanged += this.SensorChooserKinectSensorChanged;
        
        }
        //private static System.Timers.Timer aTimer;
        private static double _topBoundary;
        private static double _bottomBoundary;
        private static double _leftBoundary;
        private static double _rightBoundary;
        private static double _itemLeft;
        private static double _itemTop;

        bool closing = false;
        const int skeletonCount = 6;
        Skeleton[] allSkeletons = new Skeleton[skeletonCount];

        //
        private const double AngleChangeSmoothingFactor = 0.35;
        private const string AcceptedSpeechPrefix = "Accepted_";
        private const string RejectedSpeechPrefix = "Rejected_";

        private const int WaveImageWidth = 500;
        private const int WaveImageHeight = 100;

        private readonly SolidColorBrush greenBrush = new SolidColorBrush(Colors.Green);
        private readonly SolidColorBrush blackBrush = new SolidColorBrush(Colors.Black);

        private readonly WriteableBitmap bitmapWave;
        private readonly byte[] pixels;
        private readonly double[] energyBuffer = new double[WaveImageWidth];
        private readonly byte[] blackPixels = new byte[WaveImageWidth * WaveImageHeight];
        private readonly Int32Rect fullImageRect = new Int32Rect(0, 0, WaveImageWidth, WaveImageHeight);

        private KinectSensor kinect;
        private double angle;
        private bool running = true;
        private DispatcherTimer readyTimer;
        private EnergyCalculatingPassThroughStream stream;
        private SpeechRecognitionEngine speechRecognizer;
        //

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            kinectSensorChooser1.KinectSensorChanged += new DependencyPropertyChangedEventHandler(kinectSensorChooser1_KinectSensorChanged);
            imgbtn1.Click += new RoutedEventHandler(imgbtn1_Clicked);
            imgbtn2.Click += new RoutedEventHandler(imgbtn2_Clicked);
            imgbtn3.Click += new RoutedEventHandler(imgbtn3_Clicked);
            imgbtn4.Click += new RoutedEventHandler(imgbtn4_Clicked);
            btnStart.Click += new RoutedEventHandler(btnStart_Click);

            //ttbTimer.TimeSpan = TimeSpan.FromSeconds(0);
            ttbTimer.IsStarted = true;

            SetQuestions(1);
            SetImages(1);

        }

        void btnStart_Click(object sender, RoutedEventArgs e)
        {
            tabGame.SelectedIndex = 2;
        }

        void kinectSensorChooser1_KinectSensorChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            KinectSensor old = (KinectSensor)e.OldValue;

            StopKinect(old);

            KinectSensor sensor = (KinectSensor)e.NewValue;

            if (sensor == null)
            {
                return;
            }

            var parameters = new TransformSmoothParameters
            {
                Smoothing = 0.3f,
                Correction = 0.0f,
                Prediction = 0.0f,
                JitterRadius = 1.0f,
                MaxDeviationRadius = 0.7f
            };

            sensor.SkeletonStream.Enable(parameters);

            sensor.SkeletonStream.Enable();

            sensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(sensor_AllFramesReady);
            sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);       
            sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
            
            try
            {
                sensor.Start();
            }
            catch (System.IO.IOException)
            {
                kinectSensorChooser1.AppConflictOccurred();
            }
        }

        void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            if (closing)
            {
                return;
            }

            //Get a skeleton
            Skeleton first = GetFirstSkeleton(e);

            if (first == null)
            {
                return;
            }
            //set scaled position
            //ScalePosition(headImage, first.Joints[JointType.Head]);
            //ScalePosition(leftEllipse, first.Joints[JointType.HandLeft]);
            ScalePosition(rightEllipse, first.Joints[JointType.HandRight]);

            GetCameraPoint(first, e);

        }


        private void ScalePosition(FrameworkElement element, Joint joint)
        {
            //convert the value to X/Y
            //Joint scaledJoint = joint.ScaleTo(1280, 720); 

            //convert & scale (.3 = means 1/3 of joint distance)
            Joint scaledJoint = joint.ScaleTo(1150, 700, .30f, .30f);

            Canvas.SetLeft(element, scaledJoint.Position.X);
            Canvas.SetTop(element, scaledJoint.Position.Y);

        }
       
        void GetCameraPoint(Skeleton first, AllFramesReadyEventArgs e)
        {

            using (DepthImageFrame depth = e.OpenDepthImageFrame())
            {
                if (depth == null || kinectSensorChooser1.Kinect == null)
                {
                    return;
                }


                //Map a joint location to a point on the depth map
                //head
                //DepthImagePoint headDepthPoint =
                //    depth.MapFromSkeletonPoint(first.Joints[JointType.Head].Position);
                ////left hand
                //DepthImagePoint leftDepthPoint =
                //    depth.MapFromSkeletonPoint(first.Joints[JointType.HandLeft].Position);
                //right hand
                DepthImagePoint rightDepthPoint =
                    depth.MapFromSkeletonPoint(first.Joints[JointType.HandRight].Position);


                //Map a depth point to a point on the color image
                //head
                //ColorImagePoint headColorPoint =
                //    depth.MapToColorImagePoint(headDepthPoint.X, headDepthPoint.Y,
                //    ColorImageFormat.RgbResolution640x480Fps30);
                ////left hand
                //ColorImagePoint leftColorPoint =
                //    depth.MapToColorImagePoint(leftDepthPoint.X, leftDepthPoint.Y,
                //    ColorImageFormat.RgbResolution640x480Fps30);
                //right hand
                ColorImagePoint rightColorPoint =
                    depth.MapToColorImagePoint(rightDepthPoint.X, rightDepthPoint.Y,
                    ColorImageFormat.RgbResolution640x480Fps30);


                //Set location
                //CameraPosition(rightEllipse, rightColorPoint);

                CheckButton(imgbtn1, rightEllipse);
                CheckButton(imgbtn2, rightEllipse);
                CheckButton(imgbtn3, rightEllipse);
                CheckButton(imgbtn4, rightEllipse);
            }
        }

        //private void CameraPosition(FrameworkElement element, ColorImagePoint point)
        //{
        //    //Divide by 2 for width and height so point is right in the middle 
        //    // instead of in top/left corner
        //    Canvas.SetLeft(element, point.X - element.Width);
        //    Canvas.SetTop(element, point.Y - element.Height);

        //}

        Skeleton GetFirstSkeleton(AllFramesReadyEventArgs e)
        {
            using (SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame())
            {
                if (skeletonFrameData == null)
                {
                    return null;
                }


                skeletonFrameData.CopySkeletonDataTo(allSkeletons);

                //get the first tracked skeleton
                Skeleton first = (from s in allSkeletons
                                  where s.TrackingState == SkeletonTrackingState.Tracked
                                  select s).FirstOrDefault();

                return first;

            }
        }

        private void StopKinect(KinectSensor sensor)
        {
            if (sensor != null)
            {
                if (sensor.IsRunning)
                {
                    //stop sensor 
                    sensor.Stop();

                    //stop audio if not null
                    if (sensor.AudioSource != null)
                    {
                        sensor.AudioSource.Stop();
                    }
                }
            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            closing = true;
            StopKinect(kinectSensorChooser1.Kinect);
        }

        #region importedfrommb

        private void CheckButton(HoverButton button, Ellipse thumbStick)
        {
            if (IsItemMidpointInContainer(button, thumbStick))
            {
                button.Hovering();
            }
            else
            {
                button.Release();

            }
        }

        public bool IsItemMidpointInContainer(FrameworkElement container, FrameworkElement target)
        {
            FindValues(container, target);

            if (_itemTop < _topBoundary || _bottomBoundary < _itemTop)
            {
                //Midpoint of target is outside of top or bottom
                return false;
            }

            if (_itemLeft < _leftBoundary || _rightBoundary < _itemLeft)
            {
                //Midpoint of target is outside of left or right
                return false; 
            }

            return true;
        }

        private void FindValues(FrameworkElement container, FrameworkElement target)
        {

            if (closing)
            {
                return;
            }

            var containerTopLeft = container.PointToScreen(new Point());
            var itemTopLeft = target.PointToScreen(new Point());

            _topBoundary = containerTopLeft.Y;
            _bottomBoundary = _topBoundary + container.ActualHeight;
            _leftBoundary = containerTopLeft.X;
            _rightBoundary = _leftBoundary + container.ActualWidth;

            //use midpoint of item (width or height divided by 2)
            _itemLeft = itemTopLeft.X + (target.ActualWidth / 2);
            _itemTop = itemTopLeft.Y + (target.ActualHeight / 2);
        }

        void imgbtn1_Clicked(object sender, RoutedEventArgs e)
        {
            userans = imgbtn1.ImageSource;
            SetScore(userans, rightans);
            GetQuestions(qnum);
            SetImages(group);
            

        }

        void imgbtn2_Clicked(object sender, RoutedEventArgs e)
        {
            userans = imgbtn2.ImageSource;
            SetScore(userans, rightans);
            GetQuestions(qnum);
            SetImages(group);
            
        }

        void imgbtn3_Clicked(object sender, RoutedEventArgs e)
        {
            userans = imgbtn3.ImageSource;
            SetScore(userans, rightans);
            GetQuestions(qnum);
            SetImages(group);
            
        }

        void imgbtn4_Clicked(object sender, RoutedEventArgs e)
        {
            userans = imgbtn4.ImageSource;
            SetScore(userans, rightans);
            GetQuestions(qnum);
            SetImages(group);
            
        }

        #endregion

        private void ttbTimer_OnCountDownComplete(object sender, EventArgs e)
        {
            ttbTimer.Foreground = Brushes.Black;
            Score.addScore("user1", fsc);
            lblTestScore.Content = fsc;
            //this.Hide();
        }


        private void SetQuestions(int num)
        {
            
            switch (num)
            {
                case 1: foreach(Question q in Question.qns) 
                        {

                            if (q.number == 1)
                            {
                                lblQuestion.Content = q.question;
                                lblqn.Content = qnum + "/16";
                                rightans = q.picture;
                                qnum++;
                            }
                         }
                    

                    break;

                case 2:
                    break;

                default:
                    break;

            }

        }

        private void GetQuestions(int num)
        { 
            foreach(Question q in Question.qns) 
            {
                if (num == q.number)
                {
                    lblQuestion.Content = q.question;
                    lblqn.Content = qnum + "/16";
                    rightans = q.picture;
                    lblTestScore.Content = fsc;
                    qnum += 1;

                    if (qnum == 6)
                    {
                        group = 2;
                    }

                    if (qnum == 10)
                    {
                        group = 3;
                    }

                    if (qnum == 14)
                    {
                        group = 4;
                    }

                }

                if (num == 16)
                {
                    Score.addScore("user1", fsc);
                    lblTestScore.Content = fsc;
                }
            }
            
        }

        private void SetImages(int num)
        {
            if (group == 1)
            {
                int[] list = {1, 2, 3, 4};
                Shuffle(list);
                int p1 = list[0];
                int p2 = list[1];
                int p3 = list[2];
                int p4 = list[3];
                               
                
                foreach(Images i in Images.pix)
                {
                                           
                        if (p1 == i.number)
                        {
                            imgbtn1.ImageSource = i.path;
                            imgbtn1.ActiveImageSource = i.path;
                            lblpic1.Content = i.name;
                        }

                        if (p2 == i.number)
                        {
                            imgbtn2.ImageSource = i.path;
                            imgbtn2.ActiveImageSource = i.path;
                            lblpic2.Content = i.name;
                        }

                        if (p3 == i.number)
                        {
                            imgbtn3.ImageSource = i.path;
                            imgbtn3.ActiveImageSource = i.path;
                            lblpic3.Content = i.name;
                        }

                        if (p4 == i.number)
                        {
                            imgbtn4.ImageSource = i.path;
                            imgbtn4.ActiveImageSource = i.path;
                            lblpic4.Content = i.name;
                        }

                    }
                
                
             }

            if (group == 2)
            {
                int[] list = { 5, 6, 7, 8 };
                Shuffle(list);
                int p1 = list[0];
                int p2 = list[1];
                int p3 = list[2];
                int p4 = list[3];


                foreach (Images i in Images.pix)
                {
                    if (p1 == i.number)
                        {
                            imgbtn1.ImageSource = i.path;
                            imgbtn1.ActiveImageSource = i.path;
                            lblpic1.Content = i.name;
                        }

                        if (p2 == i.number)
                        {
                            imgbtn2.ImageSource = i.path;
                            imgbtn2.ActiveImageSource = i.path;
                            lblpic2.Content = i.name;
                        }

                        if (p3 == i.number)
                        {
                            imgbtn3.ImageSource = i.path;
                            imgbtn3.ActiveImageSource = i.path;
                            lblpic3.Content = i.name;
                        }

                        if (p4 == i.number)
                        {
                            imgbtn4.ImageSource = i.path;
                            imgbtn4.ActiveImageSource = i.path;
                            lblpic4.Content = i.name;
                        }
                }
            }

            if (group == 3)
            {
                int[] list = { 9, 10, 11, 12 };
                Shuffle(list);
                int p1 = list[0];
                int p2 = list[1];
                int p3 = list[2];
                int p4 = list[3];


                foreach (Images i in Images.pix)
                {
                    if (p1 == i.number)
                        {
                            imgbtn1.ImageSource = i.path;
                            imgbtn1.ActiveImageSource = i.path;
                            lblpic1.Content = i.name;
                        }

                        if (p2 == i.number)
                        {
                            imgbtn2.ImageSource = i.path;
                            imgbtn2.ActiveImageSource = i.path;
                            lblpic2.Content = i.name;
                        }

                        if (p3 == i.number)
                        {
                            imgbtn3.ImageSource = i.path;
                            imgbtn3.ActiveImageSource = i.path;
                            lblpic3.Content = i.name;
                        }

                        if (p4 == i.number)
                        {
                            imgbtn4.ImageSource = i.path;
                            imgbtn4.ActiveImageSource = i.path;
                            lblpic4.Content = i.name;
                        }

                    
                }

            }

            if (group == 4)
            {
                int[] list = { 13, 14, 15, 16 };
                Shuffle(list);
                int p1 = list[0];
                int p2 = list[1];
                int p3 = list[2];
                int p4 = list[3];


                foreach (Images i in Images.pix)
                {
                   
                        if (p1 == i.number)
                        {
                            imgbtn1.ImageSource = i.path;
                            imgbtn1.ActiveImageSource = i.path;
                            lblpic1.Content = i.name;
                        }

                        if (p2 == i.number)
                        {
                            imgbtn2.ImageSource = i.path;
                            imgbtn2.ActiveImageSource = i.path;
                            lblpic2.Content = i.name;
                        }

                        if (p3 == i.number)
                        {
                            imgbtn3.ImageSource = i.path;
                            imgbtn3.ActiveImageSource = i.path;
                            lblpic3.Content = i.name;
                        }

                        if (p4 == i.number)
                        {
                            imgbtn4.ImageSource = i.path;
                            imgbtn4.ActiveImageSource = i.path;
                            lblpic4.Content = i.name;
                        }

                    }
                
            }


        }

        public static void Shuffle<T>(T[] array)
        {
            Random rand = new Random();
            var random = rand;
            for (int i = array.Length; i > 1; i--)
            {
                // Pick random element to swap.
                int j = random.Next(i); // 0 <= j <= i-1
                // Swap.
                T tmp = array[j];
                array[j] = array[i - 1];
                array[i - 1] = tmp;
            }
        }

        private static RecognizerInfo GetKinectRecognizer()
        {
            Func<RecognizerInfo, bool> matchingFunc = r =>
            {
                string value;
                r.AdditionalInfo.TryGetValue("Kinect", out value);
                return "True".Equals(value, StringComparison.InvariantCultureIgnoreCase) && "en-US".Equals(r.Culture.Name, StringComparison.InvariantCultureIgnoreCase);
            };
            return SpeechRecognitionEngine.InstalledRecognizers().Where(matchingFunc).FirstOrDefault();
        }

        private void SensorChooserKinectSensorChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            KinectSensor oldSensor = e.OldValue as KinectSensor;
            if (oldSensor != null)
            {
                this.UninitializeKinect();
            }

            KinectSensor newSensor = e.NewValue as KinectSensor;
            this.kinect = newSensor;

            // Only enable this checkbox if we have a sensor
            //enableAec.IsEnabled = this.kinect != null;

            if (newSensor != null)
            {
                this.InitializeKinect();
            }
        }

        private void InitializeKinect()
        {
            var sensor = this.kinect;
            this.speechRecognizer = this.CreateSpeechRecognizer();
            try
            {
                sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
                sensor.Start();
            }
            catch (Exception)
            {
                //SensorChooser.AppConflictOccurred();
                return;
            }

            if (this.speechRecognizer != null && sensor != null)
            {
                // NOTE: Need to wait 4 seconds for device to be ready to stream audio right after initialization
                this.readyTimer = new DispatcherTimer();
                this.readyTimer.Tick += this.ReadyTimerTick;
                this.readyTimer.Interval = new TimeSpan(0, 0, 4);
                this.readyTimer.Start();

                //this.ReportSpeechStatus("Initializing audio stream...");
                //this.UpdateInstructionsText(string.Empty);

                this.Closing += this.MainWindowClosing;
            }

            this.running = true;
        }

        private void ReadyTimerTick(object sender, EventArgs e)
        {
            this.Start();
            //this.ReportSpeechStatus("Ready to recognize speech!");
            //this.UpdateInstructionsText("Say: An Alphabet");
            this.readyTimer.Stop();
            this.readyTimer = null;
        }

        private void UninitializeKinect()
        {
            var sensor = this.kinect;
            this.running = false;
            if (this.speechRecognizer != null && sensor != null)
            {
                sensor.AudioSource.Stop();
                sensor.Stop();
                this.speechRecognizer.RecognizeAsyncCancel();
                this.speechRecognizer.RecognizeAsyncStop();
            }

            if (this.readyTimer != null)
            {
                this.readyTimer.Stop();
                this.readyTimer = null;
            }
        }

        private void MainWindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            this.UninitializeKinect();
        }

        private SpeechRecognitionEngine CreateSpeechRecognizer()
        {
            RecognizerInfo ri = GetKinectRecognizer();
            if (ri == null)
            {
                MessageBox.Show(
                    @"There was a problem initializing Speech Recognition.
Ensure you have the Microsoft Speech SDK installed.",
                    "Failed to load Speech SDK",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                this.Close();
                return null;
            }

            SpeechRecognitionEngine sre;
            try
            {
                sre = new SpeechRecognitionEngine(ri.Id);
            }
            catch
            {
                MessageBox.Show(
                    @"There was a problem initializing Speech Recognition.
Ensure you have the Microsoft Speech SDK installed and configured.",
                    "Failed to load Speech SDK",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                this.Close();
                return null;
            }

            var grammar = new Choices();
            grammar.Add("a");
            grammar.Add("b");
            grammar.Add("c");
            grammar.Add("d");
            grammar.Add("e");
            grammar.Add("f");
            grammar.Add("g");
            grammar.Add("h");
            grammar.Add("i");
            grammar.Add("j");
            grammar.Add("k");
            grammar.Add("l");
            grammar.Add("m");
            grammar.Add("n");
            grammar.Add("o");
            grammar.Add("p");
            grammar.Add("q");
            grammar.Add("r");
            grammar.Add("s");
            grammar.Add("t");
            grammar.Add("u");
            grammar.Add("v");
            grammar.Add("w");
            grammar.Add("x");
            grammar.Add("y");
            grammar.Add("z");
            grammar.Add("Camera on");
            grammar.Add("Camera off");

            var gb = new GrammarBuilder { Culture = ri.Culture };

            System.Diagnostics.Debug.WriteLine(ri.Culture.DisplayName);

            gb.Append(grammar);

            // Create the actual Grammar instance, and then load it into the speech recognizer.
            var g = new Grammar(gb);

            sre.LoadGrammar(g);
            sre.SpeechRecognized += this.SreSpeechRecognized;
            //sre.SpeechHypothesized += this.SreSpeechHypothesized;
            //sre.SpeechRecognitionRejected += this.SreSpeechRecognitionRejected;

            return sre;
        }

        private void RejectSpeech(RecognitionResult result)
        {
            string status = "Rejected: " + (result == null ? string.Empty : result.Text);
            //this.ReportSpeechStatus(status);

            //Dispatcher.BeginInvoke(new Action(() => { tbColor.Background = blackBrush; }), DispatcherPriority.Normal);
        }

        private void SreSpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e)
        {
            this.RejectSpeech(e.Result);
        }

        //private void SreSpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
        //{
        //    this.ReportSpeechStatus("Hypothesized: " + e.Result.Text);
        //}

        private void SreSpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            SolidColorBrush brush;

            if (e.Result.Confidence < 0.5)
            {
                //this.RejectSpeech(e.Result);
                return;
            }

            switch (e.Result.Text.ToUpperInvariant())
            {
                case "A":
                    brush = this.greenBrush;
                    textBox1.Text = "a";
                    break;
                case "B":
                    brush = this.greenBrush;
                    textBox1.Text = "b";
                    break;
                case "C":
                    brush = this.greenBrush;
                    textBox1.Text = "c";
                    break;
                case "D":
                    brush = this.greenBrush;
                    textBox1.Text = "d";
                    break;
                case "E":
                    brush = this.greenBrush;
                    textBox1.Text = "e";
                    break;
                case "F":
                    brush = this.greenBrush;
                    textBox1.Text = "f";
                    break;
                case "G":
                    brush = this.greenBrush;
                    textBox1.Text = "g";
                    break;
                case "H":
                    brush = this.greenBrush;
                    textBox1.Text = "h";
                    break;
                case "I":
                    brush = this.greenBrush;
                    textBox1.Text = "i";
                    break;
                case "J":
                    brush = this.greenBrush;
                    textBox1.Text = "j";
                    break;
                case "K":
                    brush = this.greenBrush;
                    textBox1.Text = "K";
                    break;
                case "L":
                    brush = this.greenBrush;
                    textBox1.Text = "l";
                    break;
                case "M":
                    brush = this.greenBrush;
                    textBox1.Text = "m";
                    break;
                case "N":
                    brush = this.greenBrush;
                    textBox1.Text = "n";
                    break;
                case "O":
                    brush = this.greenBrush;
                    textBox1.Text = "o";
                    break;
                case "P":
                    brush = this.greenBrush;
                    textBox1.Text = "p";
                    break;
                case "Q":
                    brush = this.greenBrush;
                    textBox1.Text = "q";
                    break;
                case "R":
                    brush = this.greenBrush;
                    textBox1.Text = "r";
                    break;
                case "S":
                    brush = this.greenBrush;
                    textBox1.Text = "s";
                    break;
                case "T":
                    brush = this.greenBrush;
                    textBox1.Text = "t";
                    break;
                case "U":
                    brush = this.greenBrush;
                    textBox1.Text = "u";
                    break;
                case "V":
                    brush = this.greenBrush;
                    textBox1.Text = "v";
                    break;
                case "W":
                    brush = this.greenBrush;
                    textBox1.Text = "w";
                    break;
                case "X":
                    brush = this.greenBrush;
                    textBox1.Text = "x";
                    break;
                case "Y":
                    brush = this.greenBrush;
                    textBox1.Text = "y";
                    break;
                case "Z":
                    brush = this.greenBrush;
                    //textBox1.Text = "z";
                    break;

                //case "CAMERA ON":
                //    //System.Diagnostics.Process.Start("notepad.exe"); 
                //    this.kinectColorViewer1.Visibility = System.Windows.Visibility.Visible;
                //    brush = this.blackBrush;
                //    textBox1.Text = "Camera on";
                //    break;
                //case "CAMERA OFF":
                //    this.kinectColorViewer1.Visibility = System.Windows.Visibility.Hidden;
                //    brush = this.blackBrush;
                //    textBox1.Text = "Camera off";
                //    break;
                default:
                    brush = this.blackBrush;
                    break;
            }

            string status = "Recognized: " + e.Result.Text;
            //this.ReportSpeechStatus(status);

            //Dispatcher.BeginInvoke(new Action(() => { tbColor.Background = brush; }), DispatcherPriority.Normal);
        }

        //private void ReportSpeechStatus(string status)
        //{
        //    Dispatcher.BeginInvoke(new Action(() => { tbSpeechStatus.Text = status; }), DispatcherPriority.Normal);
        //}

        //private void UpdateInstructionsText(string instructions)
        //{
        //    Dispatcher.BeginInvoke(new Action(() => { tbColor.Text = instructions; }), DispatcherPriority.Normal);
        //}

        private void Start()
        {
            var audioSource = this.kinect.AudioSource;
            audioSource.BeamAngleMode = BeamAngleMode.Adaptive;
            var kinectStream = audioSource.Start();
            this.stream = new EnergyCalculatingPassThroughStream(kinectStream);
            this.speechRecognizer.SetInputToAudioStream(
                this.stream, new SpeechAudioFormatInfo(EncodingFormat.Pcm, 16000, 16, 1, 32000, 2, null));
            this.speechRecognizer.RecognizeAsync(RecognizeMode.Multiple);
            var t = new Thread(this.PollSoundSourceLocalization);
            t.Start();
        }

        private void EnableAecChecked(object sender, RoutedEventArgs e)
        {
            CheckBox enableAecCheckBox = (CheckBox)sender;
            if (enableAecCheckBox.IsChecked != null)
            {
                this.kinect.AudioSource.EchoCancellationMode = enableAecCheckBox.IsChecked.Value
                                                             ? EchoCancellationMode.CancellationAndSuppression
                                                             : EchoCancellationMode.None;
            }
        }

        private void PollSoundSourceLocalization()
        {
            while (this.running)
            {
                var audioSource = this.kinect.AudioSource;
                //if (audioSource.SoundSourceAngleConfidence > 0.5)
                //{
                //    // Smooth the change in angle
                //    double a = AngleChangeSmoothingFactor * audioSource.SoundSourceAngleConfidence;
                //    this.angle = ((1 - a) * this.angle) + (a * audioSource.SoundSourceAngle);

                //   Dispatcher.BeginInvoke(new Action(() => { rotTx.Angle = -angle; }), DispatcherPriority.Normal);
                //}

                Dispatcher.BeginInvoke(
                    new Action(
                        () =>
                        {
                            //clipConf.Rect = new Rect(
                            //    0, 0, 100 + (600 * audioSource.SoundSourceAngleConfidence), 50);
                            //string sConf = string.Format("Conf: {0:0.00}", audioSource.SoundSourceAngleConfidence);
                            //tbConf.Text = sConf;

                            stream.GetEnergy(energyBuffer);
                            this.bitmapWave.WritePixels(fullImageRect, blackPixels, WaveImageWidth, 0);

                            for (int i = 1; i < energyBuffer.Length; i++)
                            {
                                int energy = (int)(energyBuffer[i] * 5);
                                Int32Rect r = new Int32Rect(i, (WaveImageHeight / 2) - energy, 1, 2 * energy);
                                this.bitmapWave.WritePixels(r, pixels, 1, 0);
                            }
                        }),
                    DispatcherPriority.Normal);

                Thread.Sleep(50);
            }
        }

        private class EnergyCalculatingPassThroughStream : Stream
        {
            private const int SamplesPerPixel = 10;

            private readonly double[] energy = new double[WaveImageWidth];
            private readonly object syncRoot = new object();
            private readonly Stream baseStream;

            private int index;
            private int sampleCount;
            private double avgSample;

            public EnergyCalculatingPassThroughStream(Stream stream)
            {
                this.baseStream = stream;
            }

            public override long Length
            {
                get { return this.baseStream.Length; }
            }

            public override long Position
            {
                get { return this.baseStream.Position; }
                set { this.baseStream.Position = value; }
            }

            public override bool CanRead
            {
                get { return this.baseStream.CanRead; }
            }

            public override bool CanSeek
            {
                get { return this.baseStream.CanSeek; }
            }

            public override bool CanWrite
            {
                get { return this.baseStream.CanWrite; }
            }

            public override void Flush()
            {
                this.baseStream.Flush();
            }

            public void GetEnergy(double[] energyBuffer)
            {
                lock (this.syncRoot)
                {
                    int energyIndex = this.index;
                    for (int i = 0; i < this.energy.Length; i++)
                    {
                        energyBuffer[i] = this.energy[energyIndex];
                        energyIndex++;
                        if (energyIndex >= this.energy.Length)
                        {
                            energyIndex = 0;
                        }
                    }
                }
            }

            public override int Read(byte[] buffer, int offset, int count)
            {
                int retVal = this.baseStream.Read(buffer, offset, count);
                const double A = 0.3;
                lock (this.syncRoot)
                {
                    for (int i = 0; i < retVal; i += 2)
                    {
                        short sample = BitConverter.ToInt16(buffer, i + offset);
                        this.avgSample += sample * sample;
                        this.sampleCount++;

                        if (this.sampleCount == SamplesPerPixel)
                        {
                            this.avgSample /= SamplesPerPixel;

                            this.energy[this.index] = .2 + ((this.avgSample * 11) / (int.MaxValue / 2));
                            this.energy[this.index] = this.energy[this.index] > 10 ? 10 : this.energy[this.index];

                            if (this.index > 0)
                            {
                                this.energy[this.index] = (this.energy[this.index] * A) + ((1 - A) * this.energy[this.index - 1]);
                            }

                            this.index++;
                            if (this.index >= this.energy.Length)
                            {
                                this.index = 0;
                            }

                            this.avgSample = 0;
                            this.sampleCount = 0;
                        }
                    }
                }

                return retVal;
            }

            public override long Seek(long offset, SeekOrigin origin)
            {
                return this.baseStream.Seek(offset, origin);
            }

            public override void SetLength(long value)
            {
                this.baseStream.SetLength(value);
            }

            public override void Write(byte[] buffer, int offset, int count)
            {
                this.baseStream.Write(buffer, offset, count);
            }
        }
            private void SetScore(string ans, string qn)
        {
            if (ans == qn)
            {
               
                fsc += 1;
                
            }
                    
        }

        
    }

    
}
